package com.lap.auth.domain.role.service;

import com.lap.auth.application.role.dto.RoleDataScopeDto;
import com.lap.auth.domain.role.repository.RoleDataScopeRepository;
import com.lap.auth.domain.role.valueobject.DataScopeType;
import com.lap.auth.domain.role.valueobject.RoleDataScope;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public class RoleDataScopeService {

  private final RoleDataScopeRepository roleDataScopeRepository;

  public RoleDataScopeDto aggregateByRoleIds(List<Integer> roleIds) {
    List<RoleDataScope> scopes = roleDataScopeRepository.findByRoleIds(roleIds);
    if (scopes.isEmpty()) {
      return buildSelfScope();
    }

    DataScopeType finalType = DataScopeType.SELF;
    Set<Integer> mergedDeptIds = new HashSet<>();

    for (RoleDataScope scope : scopes) {
      DataScopeType type = scope.scopeType();
      if (type == DataScopeType.ALL) {
        finalType = DataScopeType.ALL;
        break;
      }

      if (type.ordinal() > finalType.ordinal()) {
        finalType = type;
      }

      if (type == DataScopeType.CUSTOM && scope.deptIdSet() != null) {
        mergedDeptIds.addAll(scope.deptIdSet());
      }

      if (type == DataScopeType.DEPT) {
        // TODO Integer deptId = userRepository.findDeptIdByUserId(UserHolder.getUserId());
        //        if (deptId != null) {
        //          mergedDeptIds.add(deptId);
        //        }
      }
    }

    return buildScope(finalType, mergedDeptIds);
  }

  private RoleDataScopeDto buildSelfScope() {
    RoleDataScopeDto dto = new RoleDataScopeDto();
    dto.setScopeType(DataScopeType.SELF.getCode());
    return dto;
  }

  private RoleDataScopeDto buildScope(DataScopeType type, Set<Integer> deptSet) {
    RoleDataScopeDto dto = new RoleDataScopeDto();
    dto.setScopeType(type.getCode());
    if (type == DataScopeType.CUSTOM || type == DataScopeType.DEPT) {
      dto.setDeptSet(deptSet);
    }
    return dto;
  }
}
